/*
 * Copyright (C) 2021 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.onurkagan.ksnack_lib.MinimalKSnack;

import ohos.agp.animation.Animator;
import ohos.agp.animation.AnimatorProperty;
import ohos.agp.components.Component;
import ohos.agp.components.ComponentContainer;
import ohos.agp.components.DependentLayout;
import ohos.agp.components.LayoutScatter;
import ohos.agp.components.Text;

import com.onurkagan.ksnack_lib.Animations.Fade;
import com.onurkagan.ksnack_lib.ResourceTable;

/**
 * MinimalKSnack
 *
 * @since 2021-07-01
 */
public class MinimalKSnack {
    /**
     * snackView
     */
    public Component snackView;
    /**
     * snackViews
     */
    public Component snackViews;
    private LayoutScatter linf;
    private ComponentContainer insertPoint;
    private MinimalKSnackBarEventListener minimalKSnackBarEventListener;
    private AnimatorProperty inAnim;
    private AnimatorProperty outAnim;
    private AnimatorProperty inAnims;
    private AnimatorProperty outAnims;

    /**
     * MinimalKSnack
     *
     * @param component
     */
    public MinimalKSnack(ComponentContainer component) {
        this.initializeMinimalBar(component);
    }

    /**
     * initializeMinimalBar
     *
     * @param component
     */
    private void initializeMinimalBar(ComponentContainer component) {
        insertPoint = (ComponentContainer) component;
        linf = LayoutScatter.getInstance(component.getContext());

        // Create view.
        snackView = linf.parse(ResourceTable.Layout_layout_snack_small, insertPoint, false);
        snackViews = linf.parse(ResourceTable.Layout_layout_snack_small, insertPoint, false);
        snackView.setVisibility(Component.INVISIBLE);
        component.addComponent(snackView);

        // Set default in anim.
        inAnim = Fade.In.getAnimation(snackView);
        inAnim = Fade.In.getAnimations(snackViews);

        // Set default out anim.
        outAnim = Fade.Out.getAnimation(snackView);
        outAnim = Fade.Out.getAnimations(snackViews);
    }

    // Message.

    /**
     * setMessage
     *
     * @param message
     * @return this
     */
    public MinimalKSnack setMessage(String message) {
        // Check null message.
        if (message == null) {
            message = "n/a";
        }

        // Initialize textview.
        Text txtMessage = (Text) snackView.findComponentById(ResourceTable.Id_minimal_snack_bar_txt_message);
        txtMessage.setText(message);
        return this;
    }

    // Set animation.

    /**
     * setAnimation
     *
     * @param inAnim
     * @param outAnim
     * @return this
     */
    public MinimalKSnack setAnimation(AnimatorProperty inAnim, AnimatorProperty outAnim) {
        this.inAnim = inAnim;
        this.outAnim = outAnim;
        return this;
    }

    // Set animation.

    /**
     * setAnimations
     *
     * @param inAnim
     * @param outAnim
     * @return this
     */
    public MinimalKSnack setAnimations(AnimatorProperty inAnim, AnimatorProperty outAnim) {
        this.inAnims = inAnim;
        this.outAnims = outAnim;
        return this;
    }

    /**
     * show
     *
     * @since 2021-07-08
     */
    public void show() {
        // Animation listener.
        inAnim.setCurve(new Animator.TimelineCurve() {
            @Override
            public float getCurvedTime(float vs) {
                return vs;
            }
        });

        inAnim.setStateChangedListener(new Animator.StateChangedListener() {
            @Override
            public void onStart(Animator animator) {
                snackView.setVisibility(Component.VISIBLE);
            }

            @Override
            public void onStop(Animator animator) {
            }

            @Override
            public void onCancel(Animator animator) {
            }

            @Override
            public void onEnd(Animator animator) {
                snackView.setVisibility(Component.VISIBLE);
            }

            @Override
            public void onPause(Animator animator) {
            }

            @Override
            public void onResume(Animator animator) {
            }
        });
        inAnim.start();

        // Start callback.
        if (minimalKSnackBarEventListener != null) {
            minimalKSnackBarEventListener.showedMinimalSnackBar();
        }
    }

    /**
     * shows
     */
    public void shows() {
        // Animation listener.
        inAnim.setCurve(new Animator.TimelineCurve() {
            @Override
            public float getCurvedTime(float vs) {
                return vs;
            }
        });

        inAnims.setStateChangedListener(new Animator.StateChangedListener() {
            @Override
            public void onStart(Animator animator) {
                snackViews.setVisibility(Component.VISIBLE);
            }

            @Override
            public void onStop(Animator animator) {
            }

            @Override
            public void onCancel(Animator animator) {
            }

            @Override
            public void onEnd(Animator animator) {
                snackViews.setVisibility(Component.VISIBLE);
            }

            @Override
            public void onPause(Animator animator) {
            }

            @Override
            public void onResume(Animator animator) {
            }
        });
        inAnims.start();

        // Start callback.
        if (minimalKSnackBarEventListener != null) {
            minimalKSnackBarEventListener.showedMinimalSnackBar();
        }
    }

    /**
     * dismiss
     */
    public void dismiss() {
        // Animation listener.
        outAnim.setStateChangedListener(new Animator.StateChangedListener() {
            @Override
            public void onStart(Animator animator) {
                snackView.setVisibility(Component.VISIBLE);
            }

            @Override
            public void onStop(Animator animator) {
            }

            @Override
            public void onCancel(Animator animator) {
            }

            @Override
            public void onEnd(Animator animator) {
                snackView.setVisibility(Component.INVISIBLE);
            }

            @Override
            public void onPause(Animator animator) {
            }

            @Override
            public void onResume(Animator animator) {
            }
        });

        // Set animation to view.
        outAnim.start();

        // Stop callback.
        if (minimalKSnackBarEventListener != null) {
            minimalKSnackBarEventListener.stoppedMinimalSnackBar();
        }
    }

    /**
     * dismisss
     */
    public void dismisss() {
        // Animation listener.
        if (outAnims == null){
            return;
        }
        outAnims.setStateChangedListener(new Animator.StateChangedListener() {
            @Override
            public void onStart(Animator animator) {
                snackViews.setVisibility(Component.VISIBLE);
            }

            @Override
            public void onStop(Animator animator) {
            }

            @Override
            public void onCancel(Animator animator) {
            }

            @Override
            public void onEnd(Animator animator) {
                snackViews.setVisibility(Component.INVISIBLE);
            }

            @Override
            public void onPause(Animator animator) {
            }

            @Override
            public void onResume(Animator animator) {
            }
        });

        // Set animation to view.
        outAnims.start();

        // Stop callback.
        if (minimalKSnackBarEventListener != null) {
            minimalKSnackBarEventListener.stoppedMinimalSnackBar();
        }
    }
}
